<?

class Smutty_Router {

	var $controller,
			$action,
			$id;

	/**
	 *  contructor.
	 *
	 */

	function Smutty_Router() {

		// interpret the URL as args
		$baseUrl = Smutty_Utils::getBaseUrl();
		$argString = substr( $_SERVER['REQUEST_URI'], strlen($baseUrl) + 1 );
		$args = explode(  '/', $argString );

		// work out default route args
		$cfg = Smutty_Config::getInstance();
		$defController = 'Index';
		$defAction = 'index';
		$defId = false;
		if ( $cfg->route->default ) {
			$defs = explode( '/', $cfg->route->default );
			if ( $defs[0] ) $defController = ucfirst($defs[0]);
			if ( $defs[1] ) $defAction = $defs[1];
			if ( $defs[2] ) $defId = $defs[2];
		}

		// set default values
		$this->controller = Smutty_Router::isValidControllerName($args[0]) ? ucfirst($args[0]) : $defController;
		$this->action = Smutty_Router::isValidActionName($args[1]) ? strtolower($args[1]) : $defAction;
		$this->id = Smutty_Router::isValidId($args[2]) ? $args[2] : $defId;

	}

	/**
	 *  tests if a given controller name is valid
	 *
	 *  @param [name] the name to test
	 *  @return boolean indicating validity
	 *
	 */

	function isValidControllerName( $name ) {
		// test is the same at the moment
		return Smutty_Router::isValidActionName( $name );
	}

	/**
	 *  tests if a given action name is valid
	 *
	 *  @param [name] the name to test
	 *  @return boolean indicating validity
	 *
	 */

	function isValidActionName( $name ) {
		// remove valid chars, if there's anything left
		// then it's not valid
		$badChars = preg_replace( '/[A-Za-z_]/', '', $name );
		return ( $name && !$badChars );
	}

	/**
	 *  tests if a given id is valid
	 *
	 *  @param [id] the id to test
	 *  @return boolean indicating validity
	 *
	 */

	function isValidId( $id ) {
		$id = (int) $id;
		return ( $id );
	}

	/**
	 *  returns the instance of this class
	 *
	 *  @return Smutty_Router
	 *
	 */

	function getInstance() {
		static $instance;
		if ( $instance == null )
			$instance = new Smutty_Router();
		return $instance;
	}

	/**
	 *  returns the name of the current controller
	 *
	 *  @return String
	 *
	 */

	function getController() {
		return $this->controller;
	}

	/**
	 *  returns the current action
	 *
	 *  @return String
	 *
	 */

	function getAction() {
		return $this->action;
	}

	/**
	 *  dispatches the request
	 *
	 */

	function dispatch() {

		// first need to include controller class
		$controllerFile = '../application/controllers/' . $this->controller . 'Controller.php';
		if ( !file_exists($controllerFile) )
			new Smutty_Exception( "'$this->controller' controller not found!" );
		require $controllerFile;

		// now instantiate controller
		$controllerClass = $this->controller . 'Controller';
		$controller = new $controllerClass();
		if ( !$controller )
			new Smutty_Exception( 'error instantiating controller' );

		// check if the given action is valid
		if ( class_exists('ReflectionClass') ) {
			$refl = new ReflectionClass( $controllerClass );
			$meth = $refl->getMethod( $this->action );
			if ( !$meth || !$meth->isPublic() )
				new Smutty_Exception( 'suitable action not found in controller' );
		}
		$action = $this->action;

		// we're ready to call the action, so get the data
		// that we're gonna pass to it and go go go!
		$controller->$action(
			$this->id,
			Smutty_Data::getInstance()
		);

	}

}

?>